//
//
//      Copyright Timothy Evans 2014 2015    timothy.evans@gsecraif.org
//
//      This file is part of gsecraif.
//
//      gsecraif is free software; you can redistribute it and/or modify
//      it under the terms of the GNU General Public License as published by
//      the Free Software Foundation; either version 3 of the License, or
//      (at your option) any later version.
//
//      See gsecraif.cpp
//
// =====================================================================
//
//! Rotate "shift" bits through "length" bytes.
//
// Array is 0 to length-1 e.g. 5 bytes is 0 to 4.
// Positive values of shift result in a right shift.
// Negative values of shift result in a left shift.
// See tech-notes documentation for information on this function.
//
// =====================================================================
// 
// Compile with g++

#include "bit_rotate.h"

using namespace std;
void bit_rotate(vector<unsigned char> original, vector<unsigned char> &rotated,
            unsigned int length, int shift)
{
unsigned short int leftshift;
unsigned short int rightshift;
unsigned short int last;
if (length) {  // lenght must be > 0
    last= length - 1;
    leftshift = abs(shift);
    rightshift = 8 - leftshift;
    if (shift > 0) {
        // right rotate "shift" bits through "length" bytes
        rotated[0] = original[last] << rightshift;
        // note we start at 0:
        for (unsigned short int byte=0; byte<=(last-1); byte++) {
            rotated[byte+1] = original[byte] << rightshift;
            }
        for (unsigned short int byte=0; byte<=last; byte++) {
            rotated[byte] = rotated[byte] | ( original[byte] >> leftshift );
            }
        }
    else if (shift < 0) {
        // left rotate "shift" bits through "length" bytes
        rotated[last] = original[0] >> rightshift;
        // note we start at 1:
        for (unsigned short int byte=1; byte<=last; byte++) {
            rotated[byte-1] = original[byte] >> rightshift;
            }
        for (unsigned short int byte=0; byte<=last; byte++) {
            rotated[byte] = rotated[byte] | ( original[byte] << leftshift );
            }
        }
    else { // (shift == 0)
        for (unsigned short int byte=0; byte<=last; byte++) {
            rotated[byte] = original[byte];
            }
        }
    } // if (length
    
}
// End of function
